package com.bonshotels;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.bonshotels.DataLayer.Hibernate.HibernateUtil;
import com.bonshotels.DomainLayer.DomainControllers.CUReservarHabitacio;
import com.bonshotels.DomainLayer.DomainModel.CategoriaHotel;
import com.bonshotels.DomainLayer.DomainModel.Client;
import com.bonshotels.DomainLayer.DomainModel.DescompteFixe;
import com.bonshotels.DomainLayer.DomainModel.DescompteVariable;
import com.bonshotels.DomainLayer.DomainModel.Habitacio;
import com.bonshotels.DomainLayer.DomainModel.Hotel;
import com.bonshotels.DomainLayer.DomainModel.Poblacio;
import com.bonshotels.DomainLayer.DomainModel.PreuTipusHabitacio;
import com.bonshotels.DomainLayer.DomainModel.Reserva;
import com.bonshotels.DomainLayer.DomainModel.SenseDescompte;
import com.bonshotels.DomainLayer.DomainModel.TipusHabitacio;
import com.bonshotels.Excepcions.ClientNoExisteix;
import com.bonshotels.Excepcions.HabitacioNoExisteix;
import com.bonshotels.Excepcions.HotelNoExisteix;
import com.bonshotels.Excepcions.HotelsNoDisp;
import com.bonshotels.Excepcions.NoHiHaPoblacions;
import com.bonshotels.Excepcions.PoblacioNoExisteix;
import com.bonshotels.Excepcions.ServeiNoDisponible;

public class MainHibernate {

	/**
	 * @param args
	 * @throws HabitacioNoExisteix 
	 * @throws ClientNoExisteix 
	 * @throws ServeiNoDisponible 
	 * @throws PoblacioNoExisteix 
	 * @throws HotelNoExisteix 
	 * @throws NoHiHaPoblacions 
	 */
	public static void main(String[] args) throws ServeiNoDisponible, ClientNoExisteix, HabitacioNoExisteix, PoblacioNoExisteix, HotelNoExisteix, NoHiHaPoblacions {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			
			Scanner sc = new Scanner(System.in);
			System.out.println("Vols poblar la BD amb el joc de proves? (Si/No)");
			String pobla = sc.nextLine();
			if (pobla.contentEquals("Si") ) {
				//insereix poblacions
		        Poblacio p1 = new Poblacio();
		        p1.setNom("Barcelona");
		        session.save(p1);
		        Poblacio p2 = new Poblacio();
		        p2.setNom("Tarragona");
		        session.save(p2);
		        Poblacio p3 = new Poblacio();
		        p3.setNom("Sant Jaume de Frontanya");
		        session.save(p3);
		        
		      //insereix categoria hotel
		        CategoriaHotel ch = new CategoriaHotel();
		        ch.setNom("GrandResort"); 
		        session.save(ch);
		        
		        //insereix tipus habitacio
		        TipusHabitacio tipus1 = new TipusHabitacio();        
		        tipus1.setNom("Suit reial");
		        tipus1.setCapacitat(6);
		        tipus1.setDescripcio("Si ets pobre, millor ni miris.");        
		        session.persist(tipus1);        
		        TipusHabitacio tipus2 = new TipusHabitacio();
		        tipus2.setNom("Habitacio doble");
		        tipus2.setCapacitat(2);
		        tipus2.setDescripcio("Si ets ric, millor ni miris.");        
		        session.persist(tipus2);
		        
		        
		        Set<Hotel> hotels1 = new HashSet<Hotel>();
		        Hotel h1 = new Hotel();
		        h1.setNom("Princess");
		        h1.setDescripcio("lalalala");
		        h1.setCategoriaHotel(ch);
		        hotels1.add(h1);
		        Hotel h2 = new Hotel();
		        h2.setNom("Juan Carlos");
		        h2.setDescripcio("lalalala");
		        h2.setCategoriaHotel(ch);
		        hotels1.add(h2);
		        p1.setHotel(hotels1);
		        session.save(h1);
		        session.save(h2);
		        session.save(p1);
		        
		        Set<Hotel> hotels2 = new HashSet<Hotel>();
		        Hotel h3 = new Hotel();
		        h3.setNom("Migdia");
		        h3.setDescripcio("lalalala");
		        h3.setCategoriaHotel(ch);
		        hotels2.add(h3);
		        Hotel h4 = new Hotel();
		        h4.setNom("Aprovarem");
		        h4.setDescripcio("lalalala");
		        h4.setCategoriaHotel(ch);
		        hotels2.add(h4);
		        p2.setHotel(hotels2);
		        session.save(h3);
		        session.save(h4);
		        session.save(p2);
		        
		        SenseDescompte sd1 = new SenseDescompte();
		        session.save(sd1);
		        DescompteFixe df1 = new DescompteFixe();
		        df1.setDescompteFixe(1);
		        session.save(df1);
		        DescompteVariable dv1 = new DescompteVariable();
		        dv1.setDescompteVariable(1);
		        session.save(dv1);
		        
		        Set<PreuTipusHabitacio> pthHotel1 = new HashSet<PreuTipusHabitacio>();
				
				PreuTipusHabitacio pth1 = new PreuTipusHabitacio();
				pth1.setPreu(6);
				pth1.setiECP(sd1);
				pth1.settH(tipus1);
				pth1.setHotel(h1);
				pthHotel1.add(pth1);
				session.save(pth1);
				
				
				PreuTipusHabitacio pth2 = new PreuTipusHabitacio();
				pth2.setPreu(7);
				pth2.setiECP(df1);
				pth2.settH(tipus2);
				pth2.setHotel(h1);
				pthHotel1.add(pth2);
				session.save(pth2);
				
				h1.setPreuTipusHabitacio(pthHotel1);
				session.update(h1);
				
				Set<PreuTipusHabitacio> pthHotel2 = new HashSet<PreuTipusHabitacio>();
				
				PreuTipusHabitacio pth3 = new PreuTipusHabitacio();
				pth3.setPreu(6);
				pth3.setiECP(dv1);
				pth3.settH(tipus1);
				pth3.setHotel(h2);
				pthHotel2.add(pth3);
				session.save(pth3);
				
				PreuTipusHabitacio pth4 = new PreuTipusHabitacio();
				pth4.setPreu(7);
				pth4.setiECP(sd1);
				pth4.settH(tipus2);
				pth4.setHotel(h2);
				pthHotel2.add(pth4);
				session.save(pth4);
				
				h2.setPreuTipusHabitacio(pthHotel2);
				session.update(h2);
				
				Set<PreuTipusHabitacio> pthHotel3 = new HashSet<PreuTipusHabitacio>();
				
				PreuTipusHabitacio pth5 = new PreuTipusHabitacio();
				pth5.setPreu(7);
				pth5.setiECP(df1);
				pth5.settH(tipus1);
				pth5.setHotel(h3);
				pthHotel3.add(pth5);
				session.save(pth5);
				
				PreuTipusHabitacio pth6 = new PreuTipusHabitacio();
				pth6.setPreu(6);
				pth6.setiECP(dv1);
				pth6.settH(tipus2);
				pth6.setHotel(h3);
				pthHotel3.add(pth6);
				session.save(pth6);
				
				h3.setPreuTipusHabitacio(pthHotel3);
				session.update(h3);
				
				Set<PreuTipusHabitacio> pthHotel4 = new HashSet<PreuTipusHabitacio>();
				
				PreuTipusHabitacio pth7 = new PreuTipusHabitacio();
				pth7.setPreu(7);
				pth7.setiECP(sd1);
				pth7.settH(tipus1);
				pth7.setHotel(h4);
				pthHotel4.add(pth7);
				session.save(pth7);
				
				
				
				PreuTipusHabitacio pth8 = new PreuTipusHabitacio();
				pth8.setPreu(6);
				pth8.setiECP(df1);
				pth8.settH(tipus2);
				pth8.setHotel(h4);
				pthHotel4.add(pth8);
				session.save(pth8);
				
				h4.setPreuTipusHabitacio(pthHotel4);
				session.update(h4);
				
				Set<Habitacio> habHotel1 = new HashSet<Habitacio>();
				
				Habitacio hab1 = new Habitacio();
				hab1.setNumero(1);
				hab1.setTipusHabitacio(tipus1);
				hab1.setHotel(h1);
				habHotel1.add(hab1);
				session.save(hab1);
		
				Habitacio hab2 = new Habitacio();
				hab2.setNumero(2);
				hab2.setTipusHabitacio(tipus1);
				hab2.setHotel(h1);
				habHotel1.add(hab2);
				session.save(hab2);
						
				Habitacio hab3 = new Habitacio();
				hab3.setNumero(3);
				hab3.setTipusHabitacio(tipus2);
				hab3.setHotel(h1);
				habHotel1.add(hab3);
				session.save(hab3);
				
				h1.setHabitacio(habHotel1);
				session.update(h1);
				
				Set<Habitacio> habHotel2 = new HashSet<Habitacio>();
				
				Habitacio hab4 = new Habitacio();
				hab4.setNumero(1);
				hab4.setTipusHabitacio(tipus1);
				hab4.setHotel(h2);
				habHotel2.add(hab4);
				session.save(hab4);
		
				Habitacio hab5 = new Habitacio();
				hab5.setNumero(2);
				hab5.setTipusHabitacio(tipus1);
				hab5.setHotel(h2);
				habHotel2.add(hab5);
				session.save(hab5);
						
				Habitacio hab6 = new Habitacio();
				hab6.setNumero(3);
				hab6.setTipusHabitacio(tipus2);
				hab6.setHotel(h2);
				habHotel2.add(hab6);
				session.save(hab6);
				
				h2.setHabitacio(habHotel2);
				session.update(h2);
				
				Set<Habitacio> habHotel3 = new HashSet<Habitacio>();
				
				Habitacio hab7 = new Habitacio();
				hab7.setNumero(1);
				hab7.setTipusHabitacio(tipus1);
				hab7.setHotel(h3);
				habHotel3.add(hab7);
				session.save(hab7);
		
				Habitacio hab8 = new Habitacio();
				hab8.setNumero(2);
				hab8.setTipusHabitacio(tipus1);
				hab8.setHotel(h3);
				habHotel3.add(hab8);
				session.save(hab8);
				
				h3.setHabitacio(habHotel3);
				session.update(h3);
				
				//clients
				Client c1 = new Client();
				c1.setNom("Marc");
				c1.setCognoms("Mauri");
				c1.setDni("dni1");
				c1.setEmail("senyorpatrons@aprovarem.net");
				session.save(c1);
				
				Client c2 = new Client();
				c2.setNom("Ana");
				c2.setCognoms("Rebollo");
				c2.setDni("dni2");
				c2.setEmail("senyoratincgana@potsersipotserno.net");
				session.save(c2);
				
				Client c3 = new Client();
				c3.setNom("Jordi");
				c3.setCognoms("Sabater");
				c3.setDni("dni3");
				c3.setEmail("senyorsuspendrem@suspendrem.net");
				session.save(c3);
		        
			}
			
	        CUReservarHabitacio cURH = new CUReservarHabitacio();
			Set<String> poblacions = cURH.obtePoblacions();
			for (String s : poblacions) {
				System.out.println(s);
			}
			System.out.println("---------Fi test obtePoblacions----------");
			
			Calendar cl1 = GregorianCalendar.getInstance();
			cl1.add(Calendar.MONTH, 1);
			Date dIni = cl1.getTime();
			cl1.add(Calendar.DAY_OF_MONTH, 5);
			Date dFi = cl1.getTime();
			try {
				Set<Map<String, Object>> habsHots = cURH.buscarHabitacio("Tarragona", dIni, dFi, 1);
				for (Map<String, Object> habHot : habsHots) {
					System.out.println( (String) habHot.get("nomHotel") );
					System.out.println( (String) habHot.get("desc") );
					System.out.println( (String) habHot.get("categoria") );
					System.out.println( ( (Float) habHot.get("avaluacio") ).toString() );				
					Set<Map<String, Object> > habs = (Set<Map<String, Object> >) habHot.get("habs");
					for (Map<String,Object> hab : habs) {
						System.out.println( (String) hab.get("tipusHab") );
						System.out.println( ( (Integer) hab.get("numeroDisp") ).toString() );
						System.out.println( ( (Float) hab.get("preu") ).toString() );
					}
				}
				System.out.println("* Busca habitacio a Barcelona");
				habsHots = cURH.buscarHabitacio("Barcelona", dIni, dFi, 1);
				for (Map<String, Object> habHot : habsHots) {
					System.out.println( (String) habHot.get("nomHotel") );
					System.out.println( (String) habHot.get("desc") );
					System.out.println( (String) habHot.get("categoria") );
					System.out.println( ( (Float) habHot.get("avaluacio") ).toString() );				
					Set<Map<String, Object> > habs = (Set<Map<String, Object> >) habHot.get("habs");
					for (Map<String,Object> hab : habs) {
						System.out.println( (String) hab.get("tipusHab") );
						System.out.println( ( (Integer) hab.get("numeroDisp") ).toString() );
						System.out.println( ( (Float) hab.get("preu") ).toString() );
					}
				}
			} catch (HotelsNoDisp e) {
				e.printStackTrace();
			}
			System.out.println("--------------Fi test buscarHabitacio--------------");
			
			Map<String,Object> infoHab = cURH.selecionarHabitacio("Princess", "Habitacio doble");	
			System.out.println( (String) infoHab.get("pob") );
			DateFormat df = new SimpleDateFormat("dd-MMMMMMMMMMMMMM-yyyy");
			System.out.println( df.format( (Date) infoHab.get("dIni") ) );
			System.out.println( df.format( (Date) infoHab.get("dFi") ) );
			System.out.println( (String) infoHab.get("hotel") );
			System.out.println( (String) infoHab.get("tipusHab") );
			System.out.println( ( (Float) infoHab.get("preuTotal") ).toString() );
			System.out.println("--------------Fi test seleccionarHabitacio--------------");
			
			Map<String,Object> habClient = cURH.introduirDni("dni1");
			System.out.println( (String) habClient.get("pob") );
			System.out.println( df.format( (Date) habClient.get("dIni") ) );
			System.out.println( df.format( (Date) habClient.get("dFi") ) );
			System.out.println( (String) habClient.get("hotel") );
			System.out.println( (String) habClient.get("tipusHab") );
			System.out.println( (String) habClient.get("dni"));
			System.out.println( (String) habClient.get("nomClient"));
			System.out.println( (String) habClient.get("cognoms"));
			System.out.println( (String) habClient.get("email"));
			System.out.println( ( (Float) habClient.get("preuTotal") ).toString() );
			System.out.println("--------------Fi test introduirDni--------------");
			
			cURH.pagament("", new Date(0) );
			System.out.println("--------------Fi test pagament--------------");

			tx.commit();
		}
		catch (RuntimeException e) {
			tx.rollback();
			throw e;
		}
		finally {
			HibernateUtil.getSessionFactory().close();
		}
		
	}

}
